package com.shop.cereshop.app.service.shop.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.app.alioss.service.FileUploadService;
import com.shop.cereshop.app.dao.shop.CerePlatformShopDAO;
import com.shop.cereshop.app.page.banner.ShopBanner;
import com.shop.cereshop.app.page.index.Product;
import com.shop.cereshop.app.page.index.RecommendShop;
import com.shop.cereshop.app.page.product.ProductCoupon;
import com.shop.cereshop.app.page.settlement.SettlementShop;
import com.shop.cereshop.app.page.shop.*;
import com.shop.cereshop.app.param.shop.ShopParam;
import com.shop.cereshop.app.param.shop.ShopPosterParam;
import com.shop.cereshop.app.redis.service.api.StringRedisService;
import com.shop.cereshop.app.service.buyer.CereBuyerShopCouponService;
import com.shop.cereshop.app.service.collect.CereBuyerCollectService;
import com.shop.cereshop.app.service.distributor.CereShopDistributorService;
import com.shop.cereshop.app.service.product.CereShopProductService;
import com.shop.cereshop.app.service.shop.*;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.collect.CereBuyerCollect;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.shop.CerePlatformShop;
import com.shop.cereshop.commons.domain.shop.CereShopReturn;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.QRCodeUtil;
import com.shop.cereshop.commons.utils.TimeUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.UUID;

@Service
public class CerePlatformShopserviceImpl implements CerePlatformShopservice {

    @Value("${weixin.appid}")
    private String appId;

    @Value("${weixin.secret}")
    private String secret;

    @Autowired
    private StringRedisService stringRedisService;

    @Autowired
    private CerePlatformShopDAO cerePlatformShopDAO;

    @Autowired
    private CereShopReturnService cereShopReturnService;

    @Autowired
    private CereShopOtherOrganizationsService cereShopOtherOrganizationsService;

    @Autowired
    private CereShopEnterpriseService cereShopEnterpriseService;

    @Autowired
    private CereShopPersonalService cereShopPersonalService;

    @Autowired
    private CereShopIndividualBusinessesService cereShopIndividualBusinessesService;

    @Autowired
    private CereBuyerCollectService cereBuyerCollectService;

    @Autowired
    private CereBuyerShopCouponService cereBuyerShopCouponService;

    @Autowired
    private CereShopProductService cereShopProductService;

    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private CereShopDistributorService cereShopDistributorService;

    /**
     * 店铺页面前缀
     */
    @Value("${shop_url}")
    private String shopUrl;

    @Override
    public List<RecommendShop> findRecommendShop() {
        return cerePlatformShopDAO.findRecommendShop();
    }

    @Override
    public RecommendShop findVolumeProductByShopId(Long shopId) {
        return cerePlatformShopDAO.findVolumeProductByShopId(shopId);
    }

    @Override
    public List<RecommendShop> findRecommendProducts() {
        return cerePlatformShopDAO.findRecommendProducts();
    }

    @Override
    public Integer findPayUsers(Long productId) {
        return cerePlatformShopDAO.findPayUsers(productId);
    }

    @Override
    public Shop getShopProducts(ShopParam param, CereBuyerUser user) throws CoBusinessException {
        //查询店铺已售件数
        Shop shop = cerePlatformShopDAO.findNumber(param.getShopId());
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<Product> list = cerePlatformShopDAO.getShopProducts(param);
        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(a -> {
                //查询付款人数
                a.setUsers(cerePlatformShopDAO.findPayUsers(a.getProductId()));
            });
        }
        PageInfo<Product> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        shop.setPage(page);
        return shop;
    }

    @Override
    public List<ShopClassify> getShopClassify(ShopParam param) throws CoBusinessException {
        return cerePlatformShopDAO.getShopClassify(param.getShopId());
    }

    @Override
    public Page getExtensionProduct(ShopParam param) throws CoBusinessException {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<Product> list = cerePlatformShopDAO.getExtensionProduct(param);
        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(a -> {
                //查询付款人数
                a.setUsers(cerePlatformShopDAO.findPayUsers(a.getProductId()));
            });
        }
        PageInfo<Product> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public List<ProductCoupon> findShopToolByProductId(Long shopId, Long productId) {
        return cerePlatformShopDAO.findShopToolByProductId(shopId, productId);
    }

    @Override
    public List<ShopBanner> getShopBanner(Long shopId) throws CoBusinessException {
        return cerePlatformShopDAO.getShopBanner(shopId);
    }

    @Override
    public Page getShops(ShopParam param, CereBuyerUser user) throws CoBusinessException {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<SettlementShop> list = cerePlatformShopDAO.getShops(param);
        if (!EmptyUtils.isEmpty(list)) {
            //查询满足条件商品数据
            list.forEach(shop -> {
                param.setShopId(shop.getShopId());
                shop.setSkus(cerePlatformShopDAO.findSkuByShopParam(param));
            });
        }
        PageInfo<SettlementShop> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public void updateState(CerePlatformShop cerePlatformShop) throws CoBusinessException {
        cerePlatformShopDAO.updateState(cerePlatformShop);
    }

    @Override
    public void insert(CerePlatformShop cerePlatformShop) throws CoBusinessException {
        cerePlatformShopDAO.insert(cerePlatformShop);
    }

    @Override
    public void update(CerePlatformShop cerePlatformShop) throws CoBusinessException {
        cerePlatformShopDAO.updateByPrimaryKeySelective(cerePlatformShop);
    }

    @Override
    public PlatformShop getById(Long shopId) throws CoBusinessException {
        //查询店铺信息
        PlatformShop shop = cerePlatformShopDAO.findShop(shopId);
        if (shop != null) {
            //查询店铺退货地址信息
            CereShopReturn cereShopReturn = cereShopReturnService.findByShopId(shopId);
            shop.setShopReturn(cereShopReturn);
            //查询认证数据
            if (IntegerEnum.getByName("主体类型-个人").equals(shop.getAuthenType())) {
                //个人认证
                shop.setPersonal(cereShopPersonalService.findByShopId(shopId));
            } else if (IntegerEnum.getByName("主体类型-个体工商户").equals(shop.getAuthenType())) {
                //个体工商户户认证
                shop.setIndividualBusinesses(cereShopIndividualBusinessesService.findByShopId(shopId));
            } else if (IntegerEnum.getByName("主体类型-企业").equals(shop.getAuthenType())) {
                //企业认证
                shop.setEnterprise(cereShopEnterpriseService.findByShopId(shopId));
            } else if (IntegerEnum.getByName("主体类型-其他组织").equals(shop.getAuthenType())) {
                //其他组织认证
                shop.setOtherOrganizations(cereShopOtherOrganizationsService.findByShopId(shopId));
            }
        }
        return shop;
    }

    @Override
    public CerePlatformShop findByShopName(String shopName) {
        return cerePlatformShopDAO.findByShopName(shopName);
    }

    @Override
    public CerePlatformShop findByPhone(String shopPhone) {
        return cerePlatformShopDAO.findByPhone(shopPhone);
    }

    @Override
    public CerePlatformShop checkShopIdByName(String shopName, Long shopId) {
        return cerePlatformShopDAO.checkShopIdByName(shopName, shopId);
    }

    @Override
    public CerePlatformShop checkShopIdByPhone(String shopPhone, Long shopId) {
        return cerePlatformShopDAO.checkShopIdByPhone(shopPhone, shopId);
    }

    @Override
    public CerePlatformShop check(String shopPhone) {
        return cerePlatformShopDAO.check(shopPhone);
    }

    @Override
    public ShopIndex getIndex(ShopParam param, CereBuyerUser user) throws CoBusinessException, Exception {
        String time = TimeUtils.yyMMddHHmmss();
        //查询店铺数据
        ShopIndex index = cerePlatformShopDAO.findShopIndex(param.getShopId());
        if (index != null) {
            //查询店铺商品总类数
            index.setClassifyNumber(cereShopProductService.findClassifyNumber(param.getShopId()).size());
            //查询店铺已售件数
            index.setNumber(cerePlatformShopDAO.findShopNumber(param.getShopId()));
            if (user != null) {
                //默认未收藏
                index.setIfCollect(IntegerEnum.NO.getCode());
                //查询收藏id
                CereBuyerCollect cereBuyerCollect = cereBuyerCollectService.findByUserShopId(user.getBuyerUserId(), index.getShopId());
                if (cereBuyerCollect != null) {
                    index.setCollectId(cereBuyerCollect.getCollectId());
                    index.setIfCollect(cereBuyerCollect.getState());
                }
            }
            //查询店铺优惠券数据
            List<ShopCoupon> coupons = cerePlatformShopDAO.findShopCoupons(param.getShopId());
            if (!EmptyUtils.isEmpty(coupons) && user != null) {
                if (user != null) {
                    //设置优惠券状态
                    for (int i = 0; i < coupons.size(); i++) {
                        if (i < 0) {
                            i = 0;
                        }
                        ShopCoupon shopCoupon = coupons.get(i);
                        //查询用户已领取的优惠券总数
                        int count = cereBuyerShopCouponService.findCount(user.getBuyerUserId(), shopCoupon.getShopCouponId());
                        if (count <= 0 && shopCoupon.getStockNumber() <= 0) {
                            //未领取过且库存数量为0，过滤这个优惠券
                            coupons.remove(i);
                            i--;
                            continue;
                        }
                        if (!EmptyUtils.isEmpty(shopCoupon.getFrequency())) {
                            //如果有限制领取次数
                            if (shopCoupon.getFrequency() == count) {
                                //如果限制领取次数=用户已领取优惠券总数,修改店铺优惠券状态为已领取
                                shopCoupon.setState(IntegerEnum.COUPON_HAVE.getCode());
                            }
                        }
                    }
                } else {
                    //未登录
                    for (int i = 0; i < coupons.size(); i++) {
                        if (i < 0) {
                            i = 0;
                        }
                        ShopCoupon shopCoupon = coupons.get(i);
                        if (shopCoupon.getStockNumber() <= 0) {
                            //如果库存小于等于0,过滤优惠券
                            coupons.remove(i);
                            i--;
                        }
                    }
                }
            }
            index.setCoupons(coupons);
            //查询拼团专区数据
            List<ShopGroupWork> shopGroupWork = cerePlatformShopDAO.findGroupWork(param.getShopId());
            if (!EmptyUtils.isEmpty(shopGroupWork)) {
                shopGroupWork.forEach(work -> {
                    //查询拼团专区商品数据
                    work.setGroupProducts(cerePlatformShopDAO.findGroupProducts(work.getShopGroupWorkId()));
                });
            }
            index.setShopGroupWork(shopGroupWork);
            //查询秒杀专区数据
            List<ShopSeckill> shopSeckill = cerePlatformShopDAO.findSeckill(param.getShopId());
            if (!EmptyUtils.isEmpty(shopSeckill)) {
                for (ShopSeckill seckill : shopSeckill) {
                    //查询秒杀专区商品数据
                    seckill.setSeckillProducts(cerePlatformShopDAO.findSeckillProducts(seckill.getShopSeckillId()));
                    //设置活动倒计时时间
                    seckill.setTime(TimeUtils.getCountDownByTime(time, seckill.getEffectiveEnd()));
                }
            }
            index.setShopSeckill(shopSeckill);
            //查询限时折扣专区数据
            List<ShopDiscount> shopDiscount = cerePlatformShopDAO.findDiscount(param.getShopId());
            if (!EmptyUtils.isEmpty(shopDiscount)) {
                for (ShopDiscount discount : shopDiscount) {
                    //查询限时折扣专区商品数据
                    discount.setDiscountProducts(cerePlatformShopDAO.findDiscountProducts(discount.getShopDiscountId()));
                    //设置活动倒计时时间
                    discount.setTime(TimeUtils.getCountDownByTime(time, discount.getEndTime()));
                }
            }
            index.setShopDiscount(shopDiscount);
        }
        return index;
    }

    @Override
    public String getSharePic(ShopPosterParam param, CereBuyerUser user) throws CoBusinessException {
        if (user == null) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        try {
            PlatformShop shop = getById(param.getShopId());
            int env = param.getTerminal();

            ShopParam shopParam = new ShopParam();
            shopParam.setShopId(param.getShopId());
            PageHelper.startPage(1, 4);
            List<Product> list = cerePlatformShopDAO.getShopProducts(shopParam);
            if (!EmptyUtils.isEmpty(list)) {
                list.forEach(a -> {
                    //查询付款人数
                    a.setUsers(cerePlatformShopDAO.findPayUsers(a.getProductId()));
                });
            }

            String shareHeadUrl = user.getHeadImage();
            String shareName = user.getName();
            if (StringUtils.isBlank(shareName)) {
                shareName = user.getWechatName();
            }
            String invitationCode = cereShopDistributorService.findInvitationCode(param.getDistributorId());
//            //获取缓存中的token
//            String accessToken = (String) stringRedisService.get(appId + secret + "accessToken");
//            Map map = null;
//            //没有在查询
//            if("".equals(accessToken)){
//                try {
//                    map = WeixinUtil.getAccessToken(appId, secret);
//                    stringRedisService.set(appId + secret + "accessToken",accessToken, Long.parseLong(map.get("expires_in").toString())*1000);
//                    accessToken = (String) map.get("access_token");
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
            return genPoster(env, shop.getShopId(), shareHeadUrl, shareName, shop.getShopBrief(), invitationCode, list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成分享海报
     *
     * @param env            1-APP 2-小程序 3-H5
     * @param shopId
     * @param shareHeadUrl
     * @param shareName
     * @param shopBrief
     * @param invitationCode
     * @param productList
     */
    private String genPoster(int env, Long shopId, String shareHeadUrl, String shareName,
                             String shopBrief, String invitationCode, List<Product> productList) throws Exception {
        int width = 434;
        int height = 702;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = image.createGraphics();

        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.OPAQUE);
        g2d.dispose();
        g2d = image.createGraphics();

        g2d.setBackground(Color.WHITE);
        g2d.clearRect(0, 0, width, height);

        g2d.setColor(new Color(182, 249, 225));
        g2d.setStroke(new BasicStroke(1));
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        BufferedImage shareHeadImg = ImageIO.read(new URL(shareHeadUrl));

        //把图片切成一个圓
        {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
            Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
            g2d.setStroke(s);
            //留一个像素的空白区域，这个很重要，画圆的时候把这个覆盖
            int border = 1;
            //图片是一个圆型
            Ellipse2D.Double shape = new Ellipse2D.Double(10, 20, 60 - border * 2, 60 - border * 2);
            //需要保留的区域
            g2d.setClip(shape);
            g2d.drawImage(shareHeadImg.getScaledInstance(58, 58, Image.SCALE_SMOOTH), 10, 20, 60 - border * 2, 60 - border * 2, null);
            g2d.dispose();
        }

        g2d = image.createGraphics();
        g2d.setStroke(new BasicStroke(1));
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        //分享人名称

        g2d.setPaint(Color.BLACK);
        g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 21));
        g2d.drawString(shareName, 85, 46);

        //店铺简介
        if (shopBrief != null) {
            g2d.setPaint(new Color(194, 194, 194));
            g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 16));
            FontMetrics fm2 = g2d.getFontMetrics(g2d.getFont());
            int shopBriefWidth = fm2.stringWidth(shopBrief);
            if (shopBriefWidth > 190) {
                shopBrief = shopBrief.substring(0, 10) + "...";
            }
            g2d.drawString(shopBrief, 85, 75);
        }

        //邀请码
        g2d.setPaint(new Color(249, 220, 116));
        g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 16));
        g2d.drawString("邀请码: " + invitationCode, 265, 66);

        //商品列表背景
        g2d.setPaint(new Color(244, 245, 247));
        g2d.setBackground(new Color(244, 245, 247));
        g2d.clearRect(8, 110, width - 8 * 2, 451);

        //商品列表
        if (!CollectionUtils.isEmpty(productList)) {
            int count = 0;
            int productHeight = 215;
            g2d.setBackground(Color.WHITE);
            for (Product product : productList) {
                int marginLeft = 222;
                if (count % 2 == 0) {
                    marginLeft = 63;
                }
                int marginTop = count / 2 * (productHeight + 8) + 120;
                int productImgWidth = 142;
                int productImgHeight = 130;
                g2d.clearRect(marginLeft, marginTop, productImgWidth, productHeight);

                BufferedImage proImg = ImageIO.read(new URL(product.getImage()));
                g2d.drawImage(proImg.getScaledInstance(productImgWidth, productImgHeight, Image.SCALE_SMOOTH), marginLeft, marginTop, null);

                //间距10

                //商品名称
                FontMetrics fmPro = g2d.getFontMetrics(g2d.getFont());
                g2d.setPaint(Color.BLACK);
                g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 12));
                //文字位置是从底部算起的，所以加上间距 还要加上字体本身
                g2d.drawString(product.getProductName(), marginLeft + 10, marginTop + productImgHeight + 10 + 12);

                //间距8

                //多少人付款
                g2d.setPaint(new Color(236, 179, 30));
                g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 10));
                g2d.drawString(product.getUsers() + "人付款", marginLeft + 10, marginTop + productImgHeight + 10 + 12 + 8 + 10);

                //间距14

                //售价 和 原价
                g2d.setPaint(new Color(225, 37, 27));
                g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 16));
                g2d.drawString("￥" + product.getPrice(), marginLeft + 10, marginTop + productImgHeight + 10 + 12 + 8 + 10 + 14 + 16);

                FontMetrics priceFm = g2d.getFontMetrics(g2d.getFont());
                int priceWidth = priceFm.stringWidth("￥" + product.getPrice());

                g2d.setPaint(Color.GRAY);
                g2d.setFont(new Font("Alibaba PuHuiTi R", Font.PLAIN, 13));
                g2d.drawString("￥" + product.getOriginalPrice(), marginLeft + 10 + priceWidth + 12, marginTop + productImgHeight + 10 + 12 + 8 + 10 + 14 + 13);
                count++;
            }
        }

        //生成底部文案 和 二维码
        g2d.setPaint(Color.BLACK);
        g2d.setFont(new Font("Alibaba PuHuiTi R", Font.BOLD, 17));
        BufferedImage qrCode = null;
        if (env == 1 || env == 2) {
//            g2d.drawString("长按识别小程序", 15, 610);
//            qrCode = WechatUtil.getWxacode(accessToken, "pages_category_page1/store/index?storeId=" + shopId);
        } else {
            g2d.drawString("扫描二维码购买商品", 15, 610);
            qrCode = QRCodeUtil.createImage(shopUrl + "storeId=" + shopId, null, false);
        }
        if (qrCode != null) {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.drawImage(qrCode, 293, 580, 120, 120, null);
        }

        g2d.dispose();

        String fileName = UUID.randomUUID().toString() + ".png";
        InputStream inputStream = bufferedImageToInputStream(image, fileName);
        return fileUploadService.uploadFile(fileName, inputStream, inputStream.available());
//        return "http://localhost:8081/images/" + fileName + "";
    }

    /**
     * 将BufferedImage转换为InputStream
     *
     * @param image
     * @return
     */
    public InputStream bufferedImageToInputStream(BufferedImage image, String fileName) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
//            boolean png = ImageIO.write(image, "png", new File("dlshop-app/src/main/resources/static/images/" + fileName + ""));
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            return input;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
